/*
 * CCreateWorld.cpp
 *
 *  Created on: 28.06.2009
 *      Author: Oli
 */

#include <Ogre.h>
#include <list>
#include <../../SDL/include/SDL/SDL.h>
#include "CCreateWorld.h"
#include "../Graphics/CGraphicEngine.h"
#include "../Physics/CPhysicsMain.h"
#include "../Objects/CLightObject.h"
#include "../Objects/CTemporaryObjects.h"

CCreateWorld::CCreateWorld()
{
}

CCreateWorld::~CCreateWorld()
{
}

void createSomeObjects(std::list<BaseObject*> *objectList)
{
    // add some stuff
    SphereObject *sphereObject = new SphereObject();
    sphereObject->radius(1);
    sphereObject->mass(1);
    sphereObject->setPosition(0,10,0.1);
    //sphereObject->setControlable(true);
    objectList->push_back(sphereObject);

    sphereObject = new SphereObject();
    sphereObject->radius(1);
    sphereObject->mass(1);
    sphereObject->setPosition(0,15,0);
    objectList->push_back(sphereObject);

    BaseObject *floorObject = new BaseObject();
    floorObject->setType(BaseObject::TYPE_FLOOR);
    floorObject->setPosition(0,0,0);
    floorObject->setProperty("material","firststep/boden_temp");
    floorObject->setProperty("sizeX","2500");
    floorObject->setProperty("sizeY","2500");
    floorObject->setProperty("elementsX","1000");
    floorObject->setProperty("elementsY","1000");
    floorObject->setProperty("meshName","MainFloor");
    objectList->push_back(floorObject);

    LightObject *lightObject = new LightObject();
    lightObject->setPosition(0,10,100);
    lightObject->setDiffuseColor(0,1,0);
    lightObject->setSpecularColor(1,0,0);
    objectList->push_back(lightObject);

    lightObject = new LightObject();
    lightObject->setPosition(0,50,-100);
    lightObject->setDiffuseColor(0,0,1);
    lightObject->setSpecularColor(0,1,0);
    objectList->push_back(lightObject);
}

void CCreateWorld::SpawnPrototypeWorld(ConfigContainer *configContainer)
{
    writeDebugOutput("I am alive! :)");
    int iExitCode = 0;
    try
    {
        CGraphicEngine ogreEngine;
        CPhysicsMain physicsWorld;
        CInputFrameListener *inputFrameListener = NULL;

        std::list<BaseObject*> objectList; // the first item in the list will be the player object
        objectList.push_back(new LivingObject() ); // we created it local. all other living object should be created on the other clients and pushed back in this list.
        inputFrameListener = new CInputFrameListener(dynamic_cast<LivingObject*>( *(objectList.begin()) ), &(configContainer->keyMapping));

        createSomeObjects(&objectList);

        writeDebugOutput("Inititialise SDL");
        if(SDL_Init(SDL_INIT_VIDEO) != 0) // Video initialises the event stuff too! (call initsubsystem for additional, well... subsystems)
        {
            writeDebugOutput("SDL failed to inititialise - aborting!");
            return;
        }

        ogreEngine.setup(&objectList, *configContainer, inputFrameListener);
        physicsWorld.setupPhysicsWorld();

        // Parse the list and add the objects to the physics and graphics worlds:
        for(std::list<BaseObject*>::iterator it = objectList.begin(); it != objectList.end(); it++)
        {
            physicsWorld.prepareObject((*it));
            if((*it)->isPhysicsRelevant())
            {
                physicsWorld.addObject((*it));
            }

            ogreEngine.prepareObject((*it));
            if((*it)->isGraphicsRelevant())
            {
                ogreEngine.addObject((*it));
            }
        }

        ogreEngine.executeRenderLoop(&physicsWorld);

        physicsWorld.destroyPhysicsWorld();
        for(std::list<BaseObject*>::iterator it = objectList.begin(); it != objectList.end(); it++)
        {
            if(*it != NULL)
                delete (*it);
        }

        if(inputFrameListener != NULL)
        {
            delete inputFrameListener;
            inputFrameListener = NULL;
        }
    }
    catch(Ogre::Exception e)
    {
        iExitCode = -2;
        writeDebugOutput(e.getFullDescription().c_str());
    }
    catch(std::exception e)
    {
        iExitCode = -1;
        writeDebugOutput(e.what());
    }
    catch(...)
    {
        iExitCode = -3;
    }

    SDL_QuitSubSystem(SDL_INIT_VIDEO);
    writeDebugOutput("Shutting down SDL");
    SDL_Quit();

    writeDebugOutput("I am going to die! :(");
}

